import { Injectable, EventEmitter } from '@angular/core';
import { Http, URLSearchParams, Response, Headers } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import { getLocalItem, removeItem } from 'utils';
import { Router } from '@angular/router';

import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';

@Injectable()
export class HttpService {

  private headers: Headers = new Headers({ 'Content-Type': 'application/json;charset=utf-8' });
  emit: EventEmitter<boolean>;

  constructor(private http:Http, private router: Router) {
    this.emit = new EventEmitter();
    if (getLocalItem('auth')) {
      const auth = getLocalItem('auth');
      this.changeHeaders('Authorization', `${auth.token_type} ${auth.access_token}`);
    }
  }

  changeHeaders(key, value) {
    if (this.headers.get(key)){
      this.headers.set(key, value);
    } else {
      this.headers.append(key, value);
    }
  }

  deleteHeaders(key) {
    this.headers.delete(key);
  }

  getHeaders() {
    return this.headers;
  }

  setHeaders(headers){
    this.headers = headers;
  }

  authError(err) {
    if(err.status === 401 && err.url.indexOf('SelfUserProfile/ForManage') === -1) {
      removeItem('auth');
      this.deleteHeaders('Authorization');
      this.emit.emit(false);
      if(this.router.url.indexOf('login') === -1) {
        this.router.navigate(['/index/login', { auth: 'unauth' }]);
      }
    }
  }

  post(url, data = null, headers = this.headers) {
    let promise = new Promise((resolve, reject) => {
      this.http.post(url, data, { headers }).map(res => res.json()).subscribe(res => {
        if (res.StatusCode) {
          if(!res.Messages){
            resolve(res.Data);
          } else {
            reject(res.Messages);
          }
        } else {
          reject(res.Messages);
        }
      }, (err) => {
        this.authError(err);
        reject(err);
      });
    });

    return promise;
  }

  get(url, data = {}, headers = this.headers) {
    let params =  new URLSearchParams();
    if (data && Object.keys(data).length > 0) {
      for (let key in data) {
        params.set(key, data[key]);
      }
    }

    let promise = new Promise((resolve, reject) => {
      this.http.get(url, {
        search: params,
        headers
      }).map(res => res.json()).subscribe(res => {
        if (res.StatusCode) {
          if(!res.Messages){
            resolve(res.Data);
          } else {
            reject(res.Messages);
          }
        } else {
          reject(res.Messages);
        }
      }, (err) => {
        this.authError(err);
        reject(err);
      });
    });

    return promise;
  }

  delete(url, data, headers = this.headers) {
    let promise = new Promise((resolve, reject) => {
      this.http.delete(url, headers).map(res => res.json()).subscribe(res => {
        if (res.StatusCode) {
          resolve(res.Data);
        } else {
          reject(res.Messages);
        }
      }, (err) => {
        this.authError(err);
        reject(err);
      });
    });
    return promise;
  }

  put(url, data, headers = this.headers) {
    let promise = new Promise((resolve, reject) => {
      this.http.put(url, headers).map(res => res.json()).subscribe(res => {
        if (res.StatusCode) {
          resolve(res.Data);
        } else {
          reject(res.Messages);
        }
      }, (err) => {
        this.authError(err);
        reject(err);
      });
    });
    return promise;
  }
}
